
use yew::prelude::*;
use yew::services::fetch::FetchTask;

use crate::service::login::LoginService;
use crate::error::Error;
use crate::utils::state::set_token;
use crate::router::WebRouter;
use crate::ob::ResultApi;
use crate::ob::login::LoginResult;

pub enum Action {
    Login,
    Account(String),
    Password(String),
    LoginDone(Result<ResultApi<LoginResult>, Error>)
}

pub struct LoginView {
    account: String,
    password: String,
    acc_msg: String,
    pwd_msg: String,
    link: ComponentLink<Self>,
    login: Callback<Result<ResultApi<LoginResult>, Error>>,
    task: Option<FetchTask>,
    service: LoginService
}

impl Component for LoginView {
    type Message = Action;
    type Properties = ();

    fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
        if crate::utils::state::get_token().is_some() {
            crate::utils::redirect::to(WebRouter::Home)
        }
        Self {
            account: String::new(), password: String::new(),
            acc_msg: String::new(), pwd_msg: String::new(),
            login: link.callback(Action::LoginDone),
            task: None, service: LoginService::new(), link
        }
    }

    fn update(&mut self, msg: Self::Message) -> bool {
        match msg {
            Action::Login => self.on_login(),
            Action::LoginDone(res) => self.login_done(res),
            Action::Account(v) => {
                if !v.is_empty() { self.acc_msg = String::new() }
                self.account = v;
                true
            },
            Action::Password(v) => {
                if !v.is_empty() { self.pwd_msg = String::new() }
                self.password = v;
                true
            }
        }
    }

    fn change(&mut self, _props: Self::Properties) -> bool {
        false
    }

    fn view(&self) -> Html {
        let link = self.link.clone();
        let on_login = link.callback(|_| Action::Login);
        let on_acc = link.callback(|e: InputData| Action::Account(e.value));
        let on_pwd = link.callback(|e: InputData| Action::Password(e.value));
        let ms_acc = crate::utils::html::err_class_msg(self.acc_msg.clone());
        let ms_pwd = crate::utils::html::err_class_msg(self.pwd_msg.clone());
        let keyup = Callback::from(move |e: KeyboardEvent| if e.key_code() == 13 {
            link.send_message(Action::Login)
        });

        html! {
            <>
                <section class="material-half-bg"><div class="cover"></div></section>
                <section class="login-content">
                    <div class="logo"><h1>{"PMsys"}</h1></div>
                    <div class="login-box">
                        <form class="login-form">
                            <h3 class="login-head"><i class="fa fa-lg fa-fw fa-user"></i>{"登陆"}</h3>
                            <div class="form-group">
                                <label class="control-label">{"用户名"}</label>
                                <input
                                    maxlength="20"
                                    oninput=on_acc
                                    class={ms_acc.1} type="text"
                                    placeholder="Account" />
                                <div class="text-danger">{ms_acc.0}</div>
                            </div>
                            <div class="form-group">
                                <label class="control-label">{"密码"}</label>
                                <input
                                    maxlength="20"
                                    oninput=on_pwd class={ms_pwd.1}
                                    onkeyup=keyup
                                    type="password"
                                    placeholder="Password" />
                                <div class="text-danger">{ms_pwd.0}</div>
                            </div>
                            <div class="form-group btn-container">
                                <button type="button" onclick=on_login class="btn btn-primary btn-block">
                                    <i class="fa fa-sign-in fa-lg fa-fw"></i>{"登陆"}
                                </button>
                            </div>
                        </form>
                    </div>
                </section>
            </>
        }
    }
}

impl LoginView {
    /// 登陆
    fn on_login(&mut self) -> bool {
        self.task = Some(self.service
            .login(&self.account, &self.password, self.login.clone()));

        false
    }
    /// 登陆回调处理
    fn login_done(&mut self, res: Result<ResultApi<LoginResult>, Error>) -> bool {
        match res {
            Ok(rlt) => {
                if rlt.is_success {
                    set_token(rlt.data.token.unwrap_or(String::new()));
                    crate::utils::redirect::to(WebRouter::Home);
                } else {
                    return if rlt.message.is_empty() {
                        self.acc_msg = rlt.data.account.unwrap_or(String::new());
                        self.pwd_msg = rlt.data.password.unwrap_or(String::new());
                        true
                    } else {
                        crate::error(rlt.message.as_str());
                        false
                    }
                }
            },
            Err(e) => crate::error(format!("{:?}", e).as_str())
        }
        false
    }
}